{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "2498ccb7",
   "metadata": {},
   "outputs": [],
   "source": [
    "deployment = \"gpt4\"\n",
    "model = \"gpt-4\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a77bb728",
   "metadata": {},
   "source": [
    "# LLM辅助设计"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "2a010569",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sure, here is a simple business domain model for a Twitter-like system represented in PlantUML script:\n",
      "\n",
      "```plantuml\n",
      "@startuml\n",
      "title Twitter-like System Domain Model\n",
      "\n",
      "class User {\n",
      "  +username: String\n",
      "  +password: String\n",
      "  +email: String\n",
      "  +createPost(content: String): Post\n",
      "  +follow(user: User)\n",
      "  +unfollow(user: User)\n",
      "}\n",
      "\n",
      "class Post {\n",
      "  +content: String\n",
      "  +timestamp: Date\n",
      "  +user: User\n",
      "  +like(user: User)\n",
      "  +retweet(user: User): Post\n",
      "}\n",
      "\n",
      "class Comment {\n",
      "  +content: String\n",
      "  +timestamp: Date\n",
      "  +user: User\n",
      "  +post: Post\n",
      "}\n",
      "\n",
      "class Notification {\n",
      "  +content: String\n",
      "  +timestamp: Date\n",
      "  +user: User\n",
      "}\n",
      "\n",
      "User \"1\" -- \"0..*\" User: follows\n",
      "User \"1\" -- \"0..*\" Post: posts\n",
      "User \"1\" -- \"0..*\" Comment: comments\n",
      "User \"1\" -- \"0..*\" Notification: notifications\n",
      "Post \"1\" -- \"0..*\" Comment: comments\n",
      "@enduml\n",
      "```\n",
      "\n",
      "In this model:\n",
      "\n",
      "- `User` class represents a user of the system. Each user has a username, password, and email. Users can create posts, follow and unfollow other users.\n",
      "- `Post` class represents a post made by a user. Each post has content, a timestamp, and a reference to the user who made the post. Posts can be liked and retweeted by users.\n",
      "- `Comment` class represents a comment made by a user on a post. Each comment has content, a timestamp, and references to the user who made the comment and the post the comment is on.\n",
      "- `Notification` class represents a notification received by a user. Each notification has content, a timestamp, and a reference to the user who received the notification.\n",
      "- Relationships between classes are represented by lines between classes. For example, a user can follow multiple users, make multiple posts, make multiple comments, and receive multiple notifications. A post can have multiple comments.\n"
     ]
    }
   ],
   "source": [
    "import openai\n",
    "response = openai.ChatCompletion.create(\n",
    "    engine=deployment, # 如果直接访问OpenAI GPT服务的同学，这里不要使用engine这个参数，要使用model，如： model=“gpt-4”\n",
    "    messages=[\n",
    "        {\"role\": \"system\", \"content\": \"You are a senior software engineer.\"},   \n",
    "        {\"role\": \"user\", \"content\": \"\"\"\n",
    "          Design a twitter like system, represent the business domain model with PlantUML script\n",
    "          \"\"\"}\n",
    "    ],\n",
    "    temperature = 0.2, \n",
    "    max_tokens = 500\n",
    "  )\n",
    "print(response.choices[0].message.content)\n",
    "# http://www.plantuml.com/plantuml"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "7e8c121f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sure, here is a simple example of a UML sequence diagram for a Facebook-like system using PlantUML script. This script represents a basic interaction where a user logs in, posts a status, and then logs out.\n",
      "\n",
      "```plantuml\n",
      "@startuml\n",
      "actor User\n",
      "participant \"Login System\" as LS\n",
      "participant \"Post System\" as PS\n",
      "participant \"Logout System\" as LOS\n",
      "\n",
      "User -> LS : Login()\n",
      "activate LS\n",
      "LS --> User : Success()\n",
      "deactivate LS\n",
      "\n",
      "User -> PS : PostStatus()\n",
      "activate PS\n",
      "PS --> User : Success()\n",
      "deactivate PS\n",
      "\n",
      "User -> LOS : Logout()\n",
      "activate LOS\n",
      "LOS --> User : Success()\n",
      "deactivate LOS\n",
      "@enduml\n",
      "```\n",
      "\n",
      "In this script:\n",
      "\n",
      "- `User` is the actor who interacts with the system.\n",
      "- `Login System`, `Post System`, and `Logout System` are the participants in the system.\n",
      "- `Login()`, `PostStatus()`, and `Logout()` are the methods that the user calls.\n",
      "- `Success()` is the response from the system to the user.\n",
      "- `activate` and `deactivate` are used to show when a participant is active in a sequence.\n",
      "\n",
      "Please note that this is a very simplified version of a Facebook-like system. A real-world system would be much more complex and involve many more participants and interactions.\n"
     ]
    }
   ],
   "source": [
    "import openai\n",
    "response = openai.ChatCompletion.create(\n",
    "    engine=deployment, # engine = \"deployment_name\".\n",
    "    messages=[\n",
    "        {\"role\": \"system\", \"content\": \"You are a senior software engineer.\"},   \n",
    "        {\"role\": \"user\", \"content\": \"\"\"\n",
    "          Design a facebook like system, represent the interactions by UML sequence diagram with PlantUML script\n",
    "          \"\"\"}\n",
    "    ],\n",
    "    temperature = 0.2, \n",
    "    max_tokens = 500\n",
    "  )\n",
    "print(response.choices[0].message.content)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "e6bc8355",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running on local URL:  http://127.0.0.1:7860\n",
      "\n",
      "To create a public link, set `share=True` in `launch()`.\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div><iframe src=\"http://127.0.0.1:7860/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": []
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain.chat_models import AzureChatOpenAI\n",
    "from langchain.memory import ConversationBufferWindowMemory\n",
    "from langchain.chains import ConversationChain\n",
    "\n",
    "# from langchain.chat_models import ChatOpenAI #直接访问OpenAI的GPT服务\n",
    "\n",
    "#llm = ChatOpenAI(model_name=\"gpt-4\", temperature=0) #直接访问OpenAI的GPT服务\n",
    "llm = AzureChatOpenAI(deployment_name = deployment, model_name=model, temperature=0, max_tokens=1000) #通过Azure的OpenAI服务\n",
    "\n",
    "\n",
    "memory = ConversationBufferWindowMemory(k=10) \n",
    "\n",
    "\n",
    "def get_response(input):\n",
    "    conversation_with_memory = ConversationChain(\n",
    "        llm=llm, \n",
    "        memory=memory,\n",
    "        verbose=False\n",
    "    )\n",
    "    return conversation_with_memory.predict(input=input)\n",
    "\n",
    "import gradio as gr\n",
    "def respond(message, chat_history):\n",
    "    bot_message = get_response(message)\n",
    "    chat_history.append((message, bot_message))\n",
    "    return \"\", chat_history\n",
    "\n",
    "with gr.Blocks() as demo:\n",
    "    chatbot = gr.Chatbot(height=300) #just to fit the notebook\n",
    "    msg = gr.Textbox(label=\"Prompt\")\n",
    "    btn = gr.Button(\"Submit\")\n",
    "    clear = gr.ClearButton(components=[msg, chatbot], value=\"Clear console\")\n",
    "\n",
    "    btn.click(respond, inputs=[msg, chatbot], outputs=[msg, chatbot])\n",
    "    msg.submit(respond, inputs=[msg, chatbot], outputs=[msg, chatbot]) #Press enter to submit\n",
    "gr.close_all()\n",
    "demo.launch()\n",
    "\n",
    "#生成一个观察者模式类图，用plantUML script表示\n",
    "#根据上面的UML生成Java代码"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0d969ddb",
   "metadata": {},
   "source": [
    "# LLM生成代码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "0199eabf",
   "metadata": {},
   "outputs": [],
   "source": [
    "from abc import ABC, abstractmethod\n",
    "\n",
    "class TokenCreator(ABC):\n",
    "    @abstractmethod\n",
    "    # create the token with uuid\n",
    "    def create_token(self, input)->str:\n",
    "        pass\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "07df4033",
   "metadata": {},
   "outputs": [],
   "source": [
    "import openai\n",
    "def work_on(input):\n",
    "    response = openai.ChatCompletion.create(\n",
    "        engine=deployment, # 如果直接访问OpenAI GPT服务的同学，这里不要使用engine这个参数，要使用model，如： model=“gpt-4”\n",
    "        messages=[\n",
    "            {\"role\": \"system\", \"content\": \"You are a senior software engineer.\"},   \n",
    "            {\"role\": \"user\", \"content\": input}\n",
    "        ],\n",
    "        temperature = 0, \n",
    "        max_tokens = 500\n",
    "      )\n",
    "    return response.choices[0].message.content"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "49cbb14a",
   "metadata": {},
   "outputs": [],
   "source": [
    "interface_def = \"\"\"\n",
    "from abc import ABC, abstractmethod\n",
    "\n",
    "class TokenCreator(ABC):\n",
    "    @abstractmethod\n",
    "    # create the token with uuid + input\n",
    "    def create_token(self, input)->str:\n",
    "        pass\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "1d52a5b7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sure, here is a simple implementation of the abstract class `TokenCreator` using the `uuid` module to generate a unique identifier:\n",
      "\n",
      "```python\n",
      "import uuid\n",
      "from abc import ABC, abstractmethod\n",
      "\n",
      "class TokenCreator(ABC):\n",
      "    @abstractmethod\n",
      "    def create_token(self, input)->str:\n",
      "        pass\n",
      "\n",
      "class MyTokenCreator(TokenCreator):\n",
      "    def create_token(self, input)->str:\n",
      "        return str(uuid.uuid4()) + input\n",
      "```\n",
      "\n",
      "In this implementation, `MyTokenCreator` is a concrete class that inherits from the abstract base class `TokenCreator`. It provides an implementation for the `create_token` method, which generates a unique token by concatenating a UUID and the input string.\n"
     ]
    }
   ],
   "source": [
    "print(work_on(\"Implement the following abstract class. \\n --- \\n\"+ interface_def))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "585c167c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "bcbecef2-643f-41b6-a50f-9cce562c8d37Hello\n"
     ]
    }
   ],
   "source": [
    "import uuid\n",
    "from abc import ABC, abstractmethod\n",
    "\n",
    "class TokenCreator(ABC):\n",
    "    @abstractmethod\n",
    "    def create_token(self, input)->str:\n",
    "        pass\n",
    "\n",
    "class MyTokenCreator(TokenCreator):\n",
    "    def create_token(self, input)->str:\n",
    "        return str(uuid.uuid4()) + input\n",
    "    \n",
    "mtc = MyTokenCreator()\n",
    "print(mtc.create_token(\"Hello\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "782ca7af",
   "metadata": {},
   "source": [
    "# 生成单元测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "e91dbbf3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sure, here is a simple unit test for the UUIDTokenCreator class using Python's built-in unittest module:\n",
      "\n",
      "```python\n",
      "import unittest\n",
      "import uuid\n",
      "from abc import ABC, abstractmethod\n",
      "\n",
      "class TokenCreator(ABC):\n",
      "    @abstractmethod\n",
      "    def create_token(self, input)->str:\n",
      "        pass\n",
      "\n",
      "class UUIDTokenCreator(TokenCreator):\n",
      "    def create_token(self, input)->str:\n",
      "        return str(uuid.uuid4()) + str(input)\n",
      "\n",
      "class TestUUIDTokenCreator(unittest.TestCase):\n",
      "    def setUp(self):\n",
      "        self.token_creator = UUIDTokenCreator()\n",
      "\n",
      "    def test_create_token(self):\n",
      "        input = \"test\"\n",
      "        token = self.token_creator.create_token(input)\n",
      "        self.assertTrue(isinstance(token, str))\n",
      "        self.assertTrue(token.endswith(input))\n",
      "\n",
      "if __name__ == '__main__':\n",
      "    unittest.main()\n",
      "```\n",
      "\n",
      "In this test, we create an instance of UUIDTokenCreator in the setUp method. Then, in the test_create_token method, we call the create_token method with a test input and assert that the returned token is a string and ends with the input string. This is a basic test and might not cover all edge cases.\n"
     ]
    }
   ],
   "source": [
    "prog = \"\"\"\n",
    "import uuid\n",
    "from abc import ABC, abstractmethod\n",
    "\n",
    "class TokenCreator(ABC):\n",
    "    @abstractmethod\n",
    "    def create_token(self, input)->str:\n",
    "        pass\n",
    "\n",
    "class UUIDTokenCreator(TokenCreator):\n",
    "    def create_token(self, input)->str:\n",
    "        return str(uuid.uuid4()) + str(input)\n",
    "\"\"\"\n",
    "\n",
    "\n",
    "print(work_on(\"Write the unit test (the unit test in the same module) for the class UUIDTokenCreator in the following code: \\n --- \\n\"+ prog))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "358df5cd",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      ".\n",
      "----------------------------------------------------------------------\n",
      "Ran 1 test in 0.002s\n",
      "\n",
      "OK\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<unittest.main.TestProgram at 0x13ce26750>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import unittest\n",
    "import uuid\n",
    "from abc import ABC, abstractmethod\n",
    "\n",
    "class TokenCreator(ABC):\n",
    "    @abstractmethod\n",
    "    def create_token(self, input)->str:\n",
    "        pass\n",
    "\n",
    "class UUIDTokenCreator(TokenCreator):\n",
    "    def create_token(self, input)->str:\n",
    "        return str(uuid.uuid4()) + str(input)\n",
    "\n",
    "class TestUUIDTokenCreator(unittest.TestCase):\n",
    "    def setUp(self):\n",
    "        self.token_creator = UUIDTokenCreator()\n",
    "\n",
    "    def test_create_token(self):\n",
    "        input = \"test\"\n",
    "        token = self.token_creator.create_token(input)\n",
    "        self.assertTrue(isinstance(token, str))\n",
    "        self.assertTrue(token.endswith(input))\n",
    "\n",
    "#if __name__ == '__main__':\n",
    "#    unittest.main()\n",
    "\n",
    "unittest.main(argv=['first-arg-is-ignored'], exit=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e647f4d7",
   "metadata": {},
   "source": [
    "# 代码理解"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "63a25caf",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "这是一个基本的Python函数，使用了requests和BeautifulSoup库来获取和解析网页内容。\n",
      "\n",
      "```python\n",
      "import requests\n",
      "from bs4 import BeautifulSoup\n",
      "\n",
      "def get_webpage_text(url):\n",
      "    try:\n",
      "        # 发送HTTP请求\n",
      "        response = requests.get(url)\n",
      "        # 检查请求状态，如果请求成功则继续\n",
      "        if response.status_code == 200:\n",
      "            # 使用BeautifulSoup解析HTML内容\n",
      "            soup = BeautifulSoup(response.content, 'html.parser')\n",
      "            # 获取所有的文本内容\n",
      "            text = soup.get_text()\n",
      "            return text\n",
      "        else:\n",
      "            return \"Failed to retrieve webpage.\"\n",
      "    except Exception as e:\n",
      "        return str(e)\n",
      "\n",
      "# 测试函数\n",
      "print(get_webpage_text('https://www.google.com'))\n",
      "```\n",
      "\n",
      "这个函数会返回网页上所有的文本内容，包括HTML标签之间的文本和JavaScript或CSS代码。如果你只想获取HTML标签之间的文本，你可以修改这个函数以只返回那部分内容。\n",
      "\n",
      "注意：在使用这个函数时，你需要确保你有权访问和抓取目标网页的内容。在某些情况下，抓取网页内容可能违反网站的服务条款。\n"
     ]
    }
   ],
   "source": [
    "prompt = \"\"\"\n",
    "编写一个Python函数，输入为一个网页地址，输出该页面上的文字内容。\n",
    "\"\"\"\n",
    "\n",
    "print(work_on(prompt))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "316109f5",
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "from bs4 import BeautifulSoup\n",
    "\n",
    "def get_webpage_text(url):\n",
    "    try:\n",
    "        # 发送HTTP请求\n",
    "        response = requests.get(url)\n",
    "        # 检查请求状态，如果请求成功则继续\n",
    "        if response.status_code == 200:\n",
    "            # 使用BeautifulSoup解析HTML内容\n",
    "            soup = BeautifulSoup(response.content, 'html.parser')\n",
    "            # 获取所有的文本内容\n",
    "            text = soup.get_text()\n",
    "            return text\n",
    "        else:\n",
    "            return \"Failed to retrieve webpage.\"\n",
    "    except Exception as e:\n",
    "        return str(e)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "0b61a480",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\"\"\"An agent designed to hold a conversation in addition to using tools.\"\"\"\n",
      "from __future__ import annotations\n",
      "\n",
      "from typing import Any, List, Optional, Sequence\n",
      "\n",
      "from langchain.agents.agent import Agent, AgentOutputParser\n",
      "from langchain.agents.agent_types import AgentType\n",
      "from langchain.agents.conversational.output_parser import ConvoOutputParser\n",
      "from langchain.agents.conversational.prompt import FORMAT_INSTRUCTIONS, PREFIX, SUFFIX\n",
      "from langchain.agents.utils import validate_tools_single_input\n",
      "from langchain.callbacks.base import BaseCallbackManager\n",
      "from langchain.chains import LLMChain\n",
      "from langchain.prompts import PromptTemplate\n",
      "from langchain.pydantic_v1 import Field\n",
      "from langchain.schema.language_model import BaseLanguageModel\n",
      "from langchain.tools.base import BaseTool\n",
      "\n",
      "\n",
      "class ConversationalAgent(Agent):\n",
      "    \"\"\"An agent that holds a conversation in addition to using tools.\"\"\"\n",
      "\n",
      "    ai_prefix: str = \"AI\"\n",
      "    \"\"\"Prefix to use before AI output.\"\"\"\n",
      "    output_parser: AgentOutputParser = Field(default_factory=ConvoOutputParser)\n",
      "    \"\"\"Output parser for the agent.\"\"\"\n",
      "\n",
      "    @classmethod\n",
      "    def _get_default_output_parser(\n",
      "        cls, ai_prefix: str = \"AI\", **kwargs: Any\n",
      "    ) -> AgentOutputParser:\n",
      "        return ConvoOutputParser(ai_prefix=ai_prefix)\n",
      "\n",
      "    @property\n",
      "    def _agent_type(self) -> str:\n",
      "        \"\"\"Return Identifier of agent type.\"\"\"\n",
      "        return AgentType.CONVERSATIONAL_REACT_DESCRIPTION\n",
      "\n",
      "    @property\n",
      "    def observation_prefix(self) -> str:\n",
      "        \"\"\"Prefix to append the observation with.\"\"\"\n",
      "        return \"Observation: \"\n",
      "\n",
      "    @property\n",
      "    def llm_prefix(self) -> str:\n",
      "        \"\"\"Prefix to append the llm call with.\"\"\"\n",
      "        return \"Thought:\"\n",
      "\n",
      "    @classmethod\n",
      "    def create_prompt(\n",
      "        cls,\n",
      "        tools: Sequence[BaseTool],\n",
      "        prefix: str = PREFIX,\n",
      "        suffix: str = SUFFIX,\n",
      "        format_instructions: str = FORMAT_INSTRUCTIONS,\n",
      "        ai_prefix: str = \"AI\",\n",
      "        human_prefix: str = \"Human\",\n",
      "        input_variables: Optional[List[str]] = None,\n",
      "    ) -> PromptTemplate:\n",
      "        \"\"\"Create prompt in the style of the zero-shot agent.\n",
      "\n",
      "        Args:\n",
      "            tools: List of tools the agent will have access to, used to format the\n",
      "                prompt.\n",
      "            prefix: String to put before the list of tools.\n",
      "            suffix: String to put after the list of tools.\n",
      "            ai_prefix: String to use before AI output.\n",
      "            human_prefix: String to use before human output.\n",
      "            input_variables: List of input variables the final prompt will expect.\n",
      "\n",
      "        Returns:\n",
      "            A PromptTemplate with the template assembled from the pieces here.\n",
      "        \"\"\"\n",
      "        tool_strings = \"\\n\".join(\n",
      "            [f\"> {tool.name}: {tool.description}\" for tool in tools]\n",
      "        )\n",
      "        tool_names = \", \".join([tool.name for tool in tools])\n",
      "        format_instructions = format_instructions.format(\n",
      "            tool_names=tool_names, ai_prefix=ai_prefix, human_prefix=human_prefix\n",
      "        )\n",
      "        template = \"\\n\\n\".join([prefix, tool_strings, format_instructions, suffix])\n",
      "        if input_variables is None:\n",
      "            input_variables = [\"input\", \"chat_history\", \"agent_scratchpad\"]\n",
      "        return PromptTemplate(template=template, input_variables=input_variables)\n",
      "\n",
      "    @classmethod\n",
      "    def _validate_tools(cls, tools: Sequence[BaseTool]) -> None:\n",
      "        super()._validate_tools(tools)\n",
      "        validate_tools_single_input(cls.__name__, tools)\n",
      "\n",
      "    @classmethod\n",
      "    def from_llm_and_tools(\n",
      "        cls,\n",
      "        llm: BaseLanguageModel,\n",
      "        tools: Sequence[BaseTool],\n",
      "        callback_manager: Optional[BaseCallbackManager] = None,\n",
      "        output_parser: Optional[AgentOutputParser] = None,\n",
      "        prefix: str = PREFIX,\n",
      "        suffix: str = SUFFIX,\n",
      "        format_instructions: str = FORMAT_INSTRUCTIONS,\n",
      "        ai_prefix: str = \"AI\",\n",
      "        human_prefix: str = \"Human\",\n",
      "        input_variables: Optional[List[str]] = None,\n",
      "        **kwargs: Any,\n",
      "    ) -> Agent:\n",
      "        \"\"\"Construct an agent from an LLM and tools.\"\"\"\n",
      "        cls._validate_tools(tools)\n",
      "        prompt = cls.create_prompt(\n",
      "            tools,\n",
      "            ai_prefix=ai_prefix,\n",
      "            human_prefix=human_prefix,\n",
      "            prefix=prefix,\n",
      "            suffix=suffix,\n",
      "            format_instructions=format_instructions,\n",
      "            input_variables=input_variables,\n",
      "        )\n",
      "        llm_chain = LLMChain(\n",
      "            llm=llm,\n",
      "            prompt=prompt,\n",
      "            callback_manager=callback_manager,\n",
      "        )\n",
      "        tool_names = [tool.name for tool in tools]\n",
      "        _output_parser = output_parser or cls._get_default_output_parser(\n",
      "            ai_prefix=ai_prefix\n",
      "        )\n",
      "        return cls(\n",
      "            llm_chain=llm_chain,\n",
      "            allowed_tools=tool_names,\n",
      "            ai_prefix=ai_prefix,\n",
      "            output_parser=_output_parser,\n",
      "            **kwargs,\n",
      "        )\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(get_webpage_text(\"https://raw.githubusercontent.com/langchain-ai/langchain/master/libs/langchain/langchain/agents/conversational/base.py\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "afd0c2dc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "这个程序定义了一个名为`ConversationalAgent`的类，它是`Agent`类的子类。`ConversationalAgent`是一个设计用于进行对话并使用工具的代理。\n",
      "\n",
      "以下是`ConversationalAgent`类的主要属性和方法：\n",
      "\n",
      "- `ai_prefix`: AI输出前的前缀，默认为\"AI\"。\n",
      "- `output_parser`: 代理的输出解析器，默认为`ConvoOutputParser`的实例。\n",
      "- `_get_default_output_parser`: 类方法，返回默认的输出解析器。\n",
      "- `_agent_type`: 属性，返回代理类型的标识符。\n",
      "- `observation_prefix`: 属性，返回观察前缀。\n",
      "- `llm_prefix`: 属性，返回llm调用的前缀。\n",
      "- `create_prompt`: 类方法，创建零射击代理的提示样式。\n",
      "- `_validate_tools`: 类方法，验证工具。\n",
      "- `from_llm_and_tools`: 类方法，从LLM和工具构造一个代理。\n",
      "\n",
      "`create_prompt`方法用于创建提示，它接收一系列工具和其他参数，然后返回一个`PromptTemplate`实例。\n",
      "\n",
      "`from_llm_and_tools`方法用于从LLM和工具构造一个代理，它接收一个LLM实例，一系列工具和其他参数，然后返回一个`ConversationalAgent`实例。\n",
      "\n",
      "此外，这个程序还使用了许多其他模块，如`langchain.agents.agent`，`langchain.agents.agent_types`，`langchain.agents.conversational.output_parser`，`langchain.agents.conversational.prompt`，`langchain.agents.utils`，`langchain.callbacks.base`，`langchain.chains`，`langchain.prompts`，`langchain.pydantic_v1`，`langchain.schema.language_model`和`langchain.tools.base`。\n"
     ]
    }
   ],
   "source": [
    "code = get_webpage_text(\"https://raw.githubusercontent.com/langchain-ai/langchain/master/libs/langchain/langchain/agents/conversational/base.py\")\n",
    "print(work_on(\"分析下面的程序：\\n ---- \\n\"+ code))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c7de5b7b",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
